﻿using System;
using System.Collections.Generic;
using System.Linq;
using Internal.Runtime.Services.BattleSkill;
using Runtime.Models;
using Runtime.Services.Battle;
using Runtime.Services.BattleAttack;

namespace Runtime.Services.BattleSkill {

    /// <summary>
    /// 效果索敌
    /// </summary>
    public interface IDFR_BattleEffectLookout {

        /// <summary>
        /// 瞭望范围
        /// </summary>
        F64 SpottingRange { get; }

        /// <summary>
        /// 地图位置
        /// </summary>
        DFR_BattleMapPosition MapPosition { get; }

        /// <summary>
        /// 可选目标
        /// </summary>
        IEnumerable<IDFR_BattleEffectTarget> Targets { get; }
    }

    [Implement(typeof(IDFR_BattleEffectLookout))]
    internal sealed class DFR_BattleEffectLookout : DFR_PoolObject, IDFR_BattleEffectLookout, IDFR_BattleEffectLookoutInternal, IDisposable {

        IDFR_BattleAttackLookout IDFR_BattleEffectLookoutInternal.AttackLookout => m_AttackLookout;

        private IDFR_BattleSkillModelTD m_SkillModel;
        private IDFR_BattleEffectModelTD m_EffectModel;
        private IDFR_BattleAttackLookout m_AttackLookout;

        protected override void Allocate() {
        }

        protected override void Release() {
            m_SkillModel = null;
            m_EffectModel = null;
            m_AttackLookout = null;
        }

        public DFR_BattleMapPosition MapPosition { get; private set; }

        public IEnumerable<IDFR_BattleEffectTarget> Targets {
            get {
                switch (m_EffectModel.TargetType) {
                    case DFR_BattleEffectTargetType.Source:
                        foreach (var kv in DFR_BattleTD.DataCenter.Models.AttackSourceDictionary.OrderBy(kv => kv.Key.Index)) {
                            yield return kv.Value.AsEffectTarget();
                        }
                        break;
                    case DFR_BattleEffectTargetType.Target:
                        foreach (var kv in DFR_BattleTD.DataCenter.Models.AttackTargetDictionary.OrderBy(kv => kv.Key.Index)) {
                            yield return kv.Value.AsEffectTarget();
                        }
                        break;
                    case DFR_BattleEffectTargetType.Road:
                        foreach (var kv in DFR_BattleTD.DataCenter.Models.CellDictionary.Where(kv => kv.Value.IsRoad).OrderBy(kv => kv.Key)) {
                            yield return kv.Value.AsSkillTarget();
                        }
                        break;
                    default:
                        throw new NotSupportedException($"未支持的参数，如有需要请联系客户端程序 [{nameof(DFR_BattleEffectTargetType)}={m_EffectModel.TargetType}]");
                }
            }
        }

        public F64 SpottingRange {
            get {
                var range = m_EffectModel.RangeType switch {
                    DFR_BattleEffectRangeType.Range => F64.From(m_EffectModel.HaloRange.Int),
                    DFR_BattleEffectRangeType.SpottingRange => m_AttackLookout.SpottingRange,
                    DFR_BattleEffectRangeType.All => F64.MaxValue,
                    _ => throw new NotSupportedException($"未支持的参数，如有需要请联系客户端程序 [{nameof(DFR_BattleEffectRangeType)}={m_EffectModel.RangeType}]"),
                };
                return range;
            }
        }

        void IDFR_BattleEffectLookoutInternal.Initialize(IDFR_BattleEffectModelTD effectModel, IDFR_BattleSkillModelTD skillModel, IDFR_BattleAttackLookout attackLookout, DFR_BattleMapPosition mapPosition) {
            m_SkillModel = skillModel;
            m_EffectModel = effectModel;
            m_AttackLookout = attackLookout;
            MapPosition = mapPosition;
        }
    }
}

namespace Internal.Runtime.Services.BattleSkill {

    public interface IDFR_BattleEffectLookoutInternal {

        IDFR_BattleAttackLookout AttackLookout { get; }

        void Initialize(IDFR_BattleEffectModelTD effectModel, IDFR_BattleSkillModelTD skillModel, IDFR_BattleAttackLookout attackLookout, DFR_BattleMapPosition mapPosition);
    }
}
